/* eslint-disable no-restricted-globals */
import React, { useEffect, useMemo, useRef, useState, forwardRef, useImperativeHandle } from 'react';
import { SearchOutlined } from '@ant-design/icons';
import classNames from 'classnames/bind';
import DoubleInput from './components/DoubleInput';
import setting from './setting';
import styled from './index.less';
import CarList from './components/CarList';

const classes = classNames.bind(styled);

const SearchResult = forwardRef(({ config, width, height, events, bigScreen, id, editable, settingData, data }, ref) => {
  const { button } = config;
  const resultData = !data ? [] : data;
  const [resultPreview, setResultPreview] = useState(false);
  const [selectedId, setSelectedId] = useState('');
  const [page, setPage] = useState(0);
  const cacheKeyWord = useRef();
  const inputRef = useRef();
  const pagination = useMemo(() => Math.ceil(resultData.length / button.rowSize), [resultData.length, button.rowSize]);
  const observerDOM = useRef();
  // 搜索框
  const searchBoxStyle = () => {
    const {
      searchConfig: { searchFontCode, searchBorderSize, searchBorderColor, searchBgColor, bgBlur, bgImg },
    } = config;
    const result = {
      backdropFilter: `blur(${bgBlur}px)`,
      border: `${searchBorderSize}px ${searchBorderColor} solid`,
      backgroundColor: searchBgColor,
      ...searchFontCode,
      width,
      height,
      display: 'flex',
    };
    if (bgImg) {
      result.backgroundImage = `url(${bgImg})`;
      result.backgroundSize = `${width - 2}px ${height - 2}px`;
      result.backgroundPosition = 'center';
    }
    return result;
  };

  // 搜索结果列表
  const resultStyle = (type) => {
    const {
      resultConfig: { defaultConfig, activeConfig },
    } = config;
    const { position, size, resultBg, bgBlur, bgImg } = defaultConfig;
    if (type === 'default') {
      return defaultConfig;
    }
    if (type === 'active') {
      return activeConfig;
    }
    const [w, h] = size.split(',');
    const [x, y] = position.split(',');
    const result = {
      backdropFilter: `blur(${bgBlur}px)`,
      backgroundColor: resultBg,
      width: `${w}px`,
      height: `${h}px`,
      left: `${x}px`,
      top: `${y}px`,
    };
    if (bgImg) {
      result.backgroundImage = `url(${bgImg})`;
      result.backgroundSize = `${w - 2}px ${h - 2}px`;
      result.backgroundPosition = 'center';
    }

    return result;
  };

  // 分页按钮样式
  const getButtonStyle = (index) => {
    const {
      defaults: { size, font, borderWidth, borderColor, backgroundColor },
      active,
    } = button;
    const box = {
      width: size,
      height: size,
      lineHeight: `${size}px`,
      cursor: index === -1 ? 'default' : 'pointer',
    };
    if (index === page) {
      return {
        border: `${active.borderWidth}px solid ${active.borderColor}`,
        background: active.backgroundColor,
        ...box,
        ...active.font,
        padding: '0px 3px',
      };
    }
    return {
      border: `${borderWidth}px solid ${borderColor}`,
      backgroundColor,
      ...box,
      ...font,
      padding: '0px 3px',
    };
  };

  // 更新store中的dataPoll
  const comSetDataPool = (dataPoll) => {
    const { setDataPool } = bigScreen;
    const { click } = events;
    setDataPool(click, dataPoll);
  };

  // 处理关闭
  const handleClose = (clearVar = true) => {
    // 清空范围缓存数据
    clearVar && (cacheKeyWord.current = '');
    // 清空变量
    clearVar && comSetDataPool({ keyWord: '', id: '' });
    // 隐藏搜索结果框
    setResultPreview(false);
    // 清空选择ID
    setSelectedId('');
    // 清空文本框内容
    clearVar && (inputRef.current.value = '');
  };

  // 处理回车查询
  const handleEnterSearch = (e) => {
    if (e.keyCode === 13) {
      if (cacheKeyWord.current) {
        comSetDataPool({ keyWord: cacheKeyWord.current, id: '' });
        setResultPreview(true);
      } else {
        handleClose();
      }
    }
  };

  // 处理点击查询
  const handleClickSearch = () => {
    if (cacheKeyWord.current) {
      comSetDataPool({ keyWord: cacheKeyWord.current, id: '' });
      setResultPreview(true);
    } else {
      handleClose();
    }
  };

  // 处理查询结果选择的ID
  const handleSelectedClick = (idV) => {
    setSelectedId(idV);
    comSetDataPool({ keyWord: cacheKeyWord.current, id: idV });
  };

  // 点击上一页下一页处理分页逻辑
  const onClickIncreasePage = (factor) => {
    if (page + factor >= pagination || page + factor < 0) return;
    setPage(page + factor);
  };

  // 更改页码
  const onClickChangePage = (index) => {
    if (index < 0) return;
    setPage(index);
  };

  // 计算获得页码内容
  const getPagesContent = () => {
    if (pagination <= 5) {
      return Array.from(new Array(pagination)).map((item, pageNumber) => (
        <span key={`page${pageNumber}`} style={getButtonStyle(pageNumber)} onClick={() => onClickChangePage(pageNumber)}>
          {pageNumber + 1}
        </span>
      ));
    }
    const curPage = page + 1;
    const pageList = [1];

    if (curPage > 3) {
      pageList.splice(1, 0, 0, curPage - 1, curPage);
    } else {
      pageList.splice(1, 0, 2, 3);
    }
    if (pagination - curPage > 2) {
      const last = pageList.pop();
      pageList.splice(pageList.length, 0, last, last + 1, 0);
    } else {
      pageList.splice(2, pageList.length);
      pageList.splice(2, 0, pagination - 3, pagination - 2, pagination - 1);
    }
    pageList.push(pagination);
    return pageList.map((pageNumber, index) => (
      <span key={`button${index}`} style={getButtonStyle(pageNumber - 1)} onClick={() => onClickChangePage(pageNumber - 1)}>
        {pageNumber || '...'}
      </span>
    ));
  };

  // 页面初始化
  useEffect(() => {
    // 初始化变量
    comSetDataPool({ keyWord: '', id: '' });
    // 所搜结果容器插入到画布层级
    const resultDiv = document.getElementById(`search_result_${id}`);
    if (resultDiv) {
      const canvasContainer = document.querySelector('.uc-flow-panel');
      canvasContainer && canvasContainer.appendChild(resultDiv);
    }

    return () => {
      const div = document.getElementById(`search_result_${id}`);
      div && div.remove();
    };
  }, []);

  // 填写变量名名时，初始化变量
  useEffect(() => {
    comSetDataPool({ keyWord: '', id: '' });
  }, [JSON.stringify(events)]);

  // 搜索结果预览配置
  useEffect(() => {
    if (editable) {
      setResultPreview(config.resultConfig.resultPriview);
    } else {
      setResultPreview(false);
    }
  }, [config.resultConfig.resultPriview]);

  // 监听组件class，根据class变化处理搜索框状态
  useEffect(() => {
    const { searchConfig } = config;
    const { isInitVar } = searchConfig;
    // 监听交互引擎是否隐藏了搜索文本框，如果隐藏则执行关闭逻辑
    const interactiveDiv = document.getElementById(`interactive_${id}`);
    if (interactiveDiv) {
      observerDOM.current && observerDOM.current.disconnect();
      observerDOM.current = new MutationObserver((mutationList) => {
        mutationList.forEach((mutation) => {
          if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
            if ([...mutation.target.classList].includes('interactiveDisplayFadeOut')) {
              handleClose(isInitVar);
            }
            if ([...mutation.target.classList].includes('interactiveDisplayFadeIn')) {
              if (inputRef.current.value) {
                setResultPreview(true);
              }
            }
          }
        });
      });
      observerDOM.current.observe(interactiveDiv, { attributes: true, attributeOldValue: true });
    }
  }, [config.searchConfig.isInitVar]);

  useImperativeHandle(ref, () => ({
    useWatchDataPool: (key, datapool) => {
      if (settingData.type === 1) {
        const myKey = events.click.fields.keyWord.mapper;
        if (myKey === key) {
          const value = datapool[key];
          if (value !== '') {
            setResultPreview(true);
          } else {
            setResultPreview(false);
          }
        }
      }
    },
  }));

  const dStyle = resultStyle('default');
  const aStyle = resultStyle('active');
  const pageStart = () => Math.min(page * button.rowSize, resultData.length);
  const pageEnd = () => Math.min(button.rowSize + pageStart(), resultData.length);
  return (
    <div className={styled['search-box']}>
      <div style={searchBoxStyle()}>
        <input
          ref={inputRef}
          placeholder={config.searchConfig.promptText}
          className={styled['search-input']}
          onChange={(e) => {
            cacheKeyWord.current = e.target.value;
          }}
          onKeyDown={handleEnterSearch}
        ></input>
        <div className={styled['search-icon']} onClick={handleClickSearch}>
          <SearchOutlined style={{ ...config.searchConfig.searchFontCode }} />
        </div>
      </div>

      <div id={`search_result_${id}`} style={resultStyle()} className={classes('search-result-box', resultPreview ? 'search-result-box-show' : '')}>
        <div className={styled['result-content']}>
          <div
            className={styled['result-title']}
            style={{
              ...dStyle.titleFontCode,
              borderBottom: dStyle.bgImg ? '0px' : ' 1px solid',
              borderColor: dStyle.titleFontCode.color,
            }}
          >
            <div>搜索结果</div>
            <div style={{ cursor: 'pointer' }} onClick={handleClose}>
              X
            </div>
          </div>
          <div className={styled['result-body']}>
            {resultData.slice(pageStart(), pageEnd()).map((m) => (
              <CarList
                aStyle={aStyle}
                dStyle={dStyle}
                isSelected={selectedId === m.id}
                className={styled['car-list']}
                onClick={() => {
                  handleSelectedClick(m.id);
                }}
              >
                <div className={styled.text} title={m.text}>
                  {m.text}
                </div>
                <div className={styled.body} title={m.desc}>
                  {m.desc}
                </div>
              </CarList>
            ))}
          </div>
          {button.open && (
            <div className={styled['result-foot']}>
              <span style={getButtonStyle()} onClick={() => onClickIncreasePage(-1)}>
                <i className="icon monetfont icon-left" />
              </span>
              {getPagesContent()}
              <span style={getButtonStyle()} onClick={() => onClickIncreasePage(1)}>
                <i className="icon monetfont icon-right" />
              </span>
            </div>
          )}
        </div>
      </div>
    </div>
  );
});

SearchResult.setting = setting;
SearchResult.styleConfig = {
  doubleInput: (props) => <DoubleInput {...props} />,
};
export default SearchResult;
